﻿using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Entities;
using Microsoft.EntityFrameworkCore;

namespace Devonline.Identity.Admin;
public class PersistedGrantService
{
    private readonly ILogger<PersistedGrantService> _logger;
    private readonly PersistedGrantDbContext _context;
    private readonly HttpContext _httpContext;
    private readonly HttpRequest _request;
    public PersistedGrantService(
        ILogger<PersistedGrantService> logger,
        PersistedGrantDbContext context,
        IHttpContextAccessor httpContextAccessor
        )
    {
        if (httpContextAccessor.HttpContext == null)
        {
            throw new ArgumentNullException(nameof(httpContextAccessor.HttpContext), "HttpContext can't be null!");
        }

        _logger = logger;
        _context = context;
        _httpContext = httpContextAccessor.HttpContext;
        _request = _httpContext.Request;
    }

    public virtual async Task<PagedResult<PersistedGrantViewModel>> GetPersistedGrantsByUsersAsync(string subject)
    {
        var queryable = _context.PersistedGrants.AsQueryable();
        if (!string.IsNullOrEmpty(subject))
        {
            queryable = queryable.Where(x => x.SubjectId.Contains(subject));
        }

        return await queryable.Select(x => new PersistedGrantViewModel
        {
            SubjectId = x.SubjectId,
            SubjectName = string.Empty
        }).Distinct().PageByAsync(_request.GetPagedRequest());
    }

    public virtual async Task<PagedResult<PersistedGrant>> GetPersistedGrantsByUserAsync(string subject) => await _context.PersistedGrants.Where(x => x.SubjectId == subject).PageByAsync(_request.GetPagedRequest());

    public virtual Task<PersistedGrant> GetPersistedGrantAsync(string key) => _context.PersistedGrants.SingleOrDefaultAsync(x => x.Key == key);

    public virtual Task<bool> ExistsPersistedGrantsAsync(string subjectId) => _context.PersistedGrants.AnyAsync(x => x.SubjectId == subjectId);

    public virtual async Task<int> DeletePersistedGrantAsync(string key)
    {
        var persistedGrant = await _context.PersistedGrants.Where(x => x.Key == key).SingleOrDefaultAsync();
        _context.PersistedGrants.Remove(persistedGrant);
        return await _context.SaveChangesAsync();
    }

    public virtual async Task<int> DeletePersistedGrantsAsync(string userId)
    {
        var grants = await _context.PersistedGrants.Where(x => x.SubjectId == userId).ToListAsync();
        _context.RemoveRange(grants);
        return await _context.SaveChangesAsync();
    }
}
